package netty.simple.groupchat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * @ClassName GroupChatServerHandler
 * @Description TODO
 * @Author director吴
 * @Date 2022/3/25 13:19
 * @Version 1.0
 **/
public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {

    //定义Channel组 管理所有的channel
    //GlobalEventExecutor.INSTANCE 是一个全局事件 执行器 -- 单例
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    //使用hashMap管理
    public static Map<String,Channel>  channels= new HashMap<String,Channel>();



    //
    SimpleDateFormat sdf =   new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    //handlerAdded 表示链接建立 - 一旦链接，就会执行此方法
    //将当前channel 加入 channelGroup
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {

        //将消息遍历发送给其他客户端
        channelGroup.writeAndFlush(new Date()  +"【客户端】"+ctx.channel().remoteAddress() + "加入聊天\n" );
        channelGroup.add(ctx.channel());
        //将加入聊天的信息 推送到其他客户端

        channels.put("id-001", ctx.channel());


    }


    //表示 channel 处于活动状态
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + "上线");

    }


    //非活动状态 触发
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {

        System.out.println(ctx.channel().remoteAddress() + "离线");
    }

    //断开链接 触发
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {

        //将消息遍历发送给其他客户端
        channelGroup.writeAndFlush(new Date()  +"【客户端】"+ctx.channel().remoteAddress() + "离开聊天\n" );

        //不需要调用  channelGroup.remove(ctx.channel()); remove 方法----- 断开链接时 自动会弹出这个channel

        System.out.println("size() =" + channelGroup.size());

    }


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {

        //获取channel
        Channel channel = ctx.channel();

        //遍历channelGroup  - 根据不同的情况 回送不同消息

        channelGroup.forEach(ch -> {
            if (channel !=ch){ //不是当前的channel
                ch.writeAndFlush(new Date() +"[客户]" + channel.remoteAddress()+"发送了消息：" + msg + "\n");
            }else {
                ch.writeAndFlush(new Date()  +"[自己]" + ctx.channel().remoteAddress()+"发送了消息：" + msg + "\n");
            }
        })   ;
    }



    //发送异常时 触发
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
